package acceptance;

import java.rmi.RemoteException ;
import java.util.HashSet ;
import java.util.Set ;

import persistence.CorruptDataException ;
import persistence.Definitions;
import persistence.PersistenceController ;
import persistence.PersistenceFactory ;
import persistence.hibernate.HibernatePersistenceFactory ;
import persistence.xstream.XStreamPersistenceFactory;
import presentation.UIThread ;
import util.Bug ;
import util.DuplicationException ;
import util.Log ;
import util.NotFoundException ;
import util.Subsystem ;
import domain.ForumData ;
import domain.LocalForum ;
import domain.message.Post ;
import domain.searchEngine.SearchEngineFactory ;
import domain.searchEngine.SearchResult ;
import domain.searchEngine.compass.CompassSearchEngineFactory ;
import domain.searchEngine.origin.OriginSearchEngineFactory;
import domain.user.UnpermittedActionException ;


/**
*
*/
public class RealBridge implements IBridge
{

	/**
	 * IMPORTANT!!!!
	 * if we want the tests to run with a real bridge(meaning that there is an application)
	 * then  IMPLEMENTED = true
	 * if we want the tests to run with a proxy bridge (no application - only stub)
	 * then  IMPLEMENTED = false
	 */
	public static final boolean IMPLEMENTED = true;

	ForumData data = null;
	SearchEngineFactory searchProvider = null;
	PersistenceFactory persistenceProvider = null ;
	private static LocalForum theForum = null;




	//hard coded initialization. temporary only (for self testings)

	/**
	 * constructor that creates a new forum (with no prior data)
	 */
	public RealBridge(){

	}

	public boolean addModaratorPrivileges(final long adminId,final String userName){
		try{
			RealBridge.theForum.addModeratorPrivileges(adminId, userName);
			return true;
		}catch (NotFoundException e)
		{
			return false;
		}catch (UnpermittedActionException e)
		{
			return false;
		}
	}

	public Post addPost(final long threadId,final String msg,final long writerId){
		try{
			Post myPost = (Post)(RealBridge.theForum.addPost(threadId, writerId, msg));
			return myPost;
		}catch (NotFoundException e)
		{
			return null;
		}catch (UnpermittedActionException e)
		{
			return null;
		}

	}

	public void createNewData(){
		try
		{
			this.clearDatabase() ;
			/*
			HibernatePersistenceFactory hibernate = new HibernatePersistenceFactory(PersistenceController.BUILD_NEW) ;
			this.persistenceProvider = hibernate ;
			this.data = new ForumData(this.persistenceProvider);
			this.searchProvider = new CompassSearchEngineFactory(hibernate, this.data) ;
			*/
			
			XStreamPersistenceFactory xstream = new XStreamPersistenceFactory(PersistenceController.BUILD_NEW, Definitions.getXmlFiles()) ;
			this.persistenceProvider = xstream ;
			this.data = new ForumData(this.persistenceProvider) ;
			this.searchProvider = new OriginSearchEngineFactory(Definitions.INDEX_URI, this.data) ;
			
			RealBridge.theForum = new LocalForum(this.data, this.searchProvider);
			
		}
		catch (final CorruptDataException e)
		{
			Log.getLogger(Subsystem.PRESENTATION_MODEL).info("Corrupted data exception thrown in making of forum") ;

		}
		catch (final RemoteException e)
		{
			Log.getLogger(Subsystem.PRESENTATION_MODEL).info("Remote problems thrown in making of forum") ;
		}
		catch (Exception e)
		{
			Log.getLogger(Subsystem.PRESENTATION_MODEL).info("ecxeption thrown in making of forum") ;
		}
	}

	@Override
	public UIThread createNewThread(final String topic, final long userId)
	{
		try
		{
			return RealBridge.theForum.addThread(RealBridge.theForum.getRootDirectory().getId(), userId, topic, "thread start");
		}
		catch (UnpermittedActionException e)
		{
			return null;
		}
		catch (NotFoundException e)
		{
			return null;

		}
	}

	public boolean deletePost(final long userId, final long postId, final long threadId){
		try{
			RealBridge.theForum.deletePost(userId,postId,threadId);
			return true;
		}catch (NotFoundException e)
		{
			return false;
		}catch (UnpermittedActionException e)
		{
			return false;
		}
	}

	/**
	 * @param username - the username of the person who wants to login
	 * @param password - the password of the person who wants to login
	 * @return true if succsseful of false otherwise
	 */
	@Override
	public boolean login(final String username, final String password) {
		try
		{
			RealBridge.theForum.login(username, password);
			return true;
		}
		catch (Exception e)
		{
			return false;
		}
	}

	public boolean logout(final long userId){
		try{
			RealBridge.theForum.logout(userId);
			return true;
		}catch (NotFoundException e)
		{
			return false;
		}catch (UnpermittedActionException e)
		{
			return false;
		}catch (Exception e)
		{
			return false ;
		}
	}

	/**
	 * @param username - the username of the person who wants to register
	 * @param password - the password of the person who wants to register
	 * @return true if succsseful of false otherwise
	 */
	@Override
	public boolean register(final String username, final String password) {
		try
		{
			RealBridge.theForum.register(username, password);
			return true;
		}
		catch (DuplicationException e)
		{
			return false;
		}
		catch (Exception e)
		{
			return false;
		}
	}

	public boolean searchForMessageByCategories(final String authorName, final String msg){
		Set<SearchResult> ans1 = new HashSet<SearchResult>();
		Set<SearchResult> ans2 = new HashSet<SearchResult>();
		ans1 = RealBridge.theForum.searchByAuthor(authorName);
		ans2 = RealBridge.theForum.searchByContent(msg);
		return ans1.size()==2 ;
	}

	private void clearDatabase()
	{
		try
		{
			this.persistenceProvider = new HibernatePersistenceFactory(PersistenceController.BUILD_NEW) ;
			this.persistenceProvider.newMemberPersistence().close() ;
		}
		catch (CorruptDataException e)
		{
			throw new Bug("report corrupt data when no data expected") ;
		}
	}

}
